package com.anlu.base.common.log.event;

import com.anlu.base.admin.api.entity.SysLog;
import com.anlu.base.admin.api.feign.RemoteLogService;
import com.anlu.base.common.core.jakson.PigJavaTimeModule;
import com.anlu.base.common.log.config.PigLogProperties;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;

import java.util.Objects;
import java.util.Properties;

@Slf4j
@RequiredArgsConstructor
public class SysLogListener implements InitializingBean {

    // new 一个 避免日志脱敏策略影响全局ObjectMapper
    private final static ObjectMapper objectMapper = new ObjectMapper();


    private final RemoteLogService remoteLogService;

    private final PigLogProperties pigLogProperties;


    @SneakyThrows
    @Async
    @Order
    @EventListener(SysLogEvent.class)
    public void saveSysLog(SysLogEvent event) {
        SysLogEventSource source = (SysLogEventSource) event.getSource();
        SysLog sysLog = new SysLog();
        BeanUtils.copyProperties(source,sysLog);

        if(Objects.nonNull(source.getBody())){
            String params = objectMapper.writeValueAsString(source.getBody());
            sysLog.setParams(params);
        }
        remoteLogService.saveLog(sysLog);

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class);

        String[] ignorableFieldNames = pigLogProperties.getExcludeFields().toArray(new String[0]);

        FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
        objectMapper.setFilterProvider(filters);
        objectMapper.registerModule(new PigJavaTimeModule());
    }


    @JsonFilter("filter properties by name")
    class PropertyFilterMixIn {

    }
}
